package com.ruoyi.business.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.ruoyi.common.exception.ServiceException;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * @author liutao
 * @version 1.0
 * @description: TODO
 * @date 2023/10/19 12:38
 */
public class AddWatermarkUtil {
    //定义图片水印字体类型
    public static final String FONT_NAME = "宋体";

    private static final int FONT_STYLE = Font.ITALIC;
    private static final int FONT_SIZE = 30;
    private static final Color FONT_COLOR = Color.black;

    private static final float ALPHA = 0.1F;

    // 添加多条文字水印
    public static Boolean moreTextWaterMark(String sourcePath, String outputPath, String imageName, String imageType)
            throws IOException {
        String MARK_TEXT = "这是一段长文字水印这是一段长文字水印这是一段长文字水印这是一段长文字水印这是一段长文字水印";
        // 读取原图片信息
        File file = new File(sourcePath);

        if (!file.isFile()) {
            return false;
        }

        // 获取源图像的宽度、高度
        Image image = ImageIO.read(file);
        // 计算原始图片宽度长度
        int width = image.getWidth(null);
        int height = image.getHeight(null);
        // 创建图片缓存对象
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 创建java绘图工具对象
        Graphics2D graphics2d = bufferedImage.createGraphics();
        // 参数主要是，原图，坐标，宽高
        graphics2d.drawImage(image, 0, 0, width, height, null);
        graphics2d.setFont(new Font(FONT_NAME, FONT_STYLE, FONT_SIZE));
        graphics2d.setColor(FONT_COLOR);

        // 使用绘图工具将水印绘制到图片上
        // 计算文字水印宽高值
        int waterWidth = FONT_SIZE * getTextLength(MARK_TEXT);
        int waterHeight = FONT_SIZE;

        // 水印透明设置
        graphics2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, ALPHA));
        graphics2d.rotate(Math.toRadians(30), (double) bufferedImage.getWidth() / 2, (double) bufferedImage.getHeight() / 2);

        int x = -width / 2;
        int y = -height / 2;

        while (x < width * 1.5) {
            y = -height / 2;
            while (y < height * 1.5) {
                graphics2d.drawString(MARK_TEXT, x, y);
                y += waterHeight + 100;
            }
            x += waterWidth + 100;
        }
        graphics2d.dispose();

        // 输出图片
        File sf = new File(outputPath, imageName + "." + imageType);
        // 保存图片
        ImageIO.write(bufferedImage, imageType, sf);
        return true;

    }

    // 计算水印文本长度
    // 1、中文长度即文本长度 2、英文长度为文本长度二分之一
    public static int getTextLength(String text) {
        // 水印文字长度
        int length = text.length();

        for (int i = 0; i < text.length(); i++) {
            String s = String.valueOf(text.charAt(i));
            if (s.getBytes().length > 1) {
                length++;
            }
        }
        length = length % 2 == 0 ? length / 2 : length / 2 + 1;
        return length;
    }

    public static void waterPress(String srcImgPath, Color markContentColor, int fontSize, List<String> waterMarkContentList) {

        // 读取原图片信息
        File srcImgFile = new File(srcImgPath);
        // 1、源图片
        Image srcImg = null;
        try {
            srcImg = ImageIO.read(srcImgFile);
        } catch (IOException e) {
            throw new ServiceException("读取图片文件失败");
        }
        // 原图宽度
        int srcImgWidth = srcImg.getWidth(null);
        // 原图高度
        int srcImgHeight = srcImg.getHeight(null);
        // 加水印
        BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
        // 得到画笔对象
        Graphics2D g = bufImg.createGraphics();

        // 3、设置对线段的锯齿状边缘处理
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

        //开始绘图
        g.fillRect(0, 0, srcImgWidth, srcImgHeight);//通过使用当前绘图表面的背景色进行填充来清除指定的矩形。
        // 设置起点
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);

        // 获取水印文字中最长的
//        int maxLength = 0;
//        for (String s : waterMarkContentList) {
//            int fontLen = getWatermarkLength(s, g);
//            if (maxLength < fontLen) {
//                maxLength = fontLen;
//            }
//        }
        int waterWidth = (srcImgWidth / 2) + fontSize + 10;

        Font font = new Font(FONT_NAME, Font.PLAIN, fontSize);

        // 根据图片的背景设置水印颜色
        g.setColor(markContentColor);
        // 设置水印文字字体
        g.setFont(font);


        int contentLength = waterMarkContentList.size();

        int huanHangCount = 0;

        int tempX = 20;
        int firstY = 0;
        int endY = 0;

        int bgWidthLen = 0;

        for (int j = 0; j < contentLength; j++) {
            String waterMarkContent = waterMarkContentList.get(j);

            // 文字叠加,自动换行叠加
//            int tempX = 20;
            int tempY = srcImgHeight - fontSize * (contentLength - j) - 80;
            if (j == 0) {
                firstY = tempY;
            }
            int tempCharLen = 0;// 单字符长度
            int tempLineLen = 0;// 单行字符总长度临时计算
            // 获取水印文字总长度
            int fontlen = getWatermarkLength(waterMarkContent, g);
//            int line = fontlen / waterWidth;// 文字长度相对于图片宽度应该有多少行

            if (huanHangCount > 0) {
                tempY = tempY + fontSize * huanHangCount;
            }
            bgWidthLen = j + huanHangCount;
            if (j == contentLength-1) {
                endY = tempY;
            }

//            System.out.println("水印文字总长度:" + fontlen + ",图片宽度:" + srcImgWidth + ",图片高度:" + srcImgHeight + ",字符个数:" + waterMarkContent.length() + ",文字行数:" + line + ",x初始坐标:" + tempX + ",y初始坐标:" + tempY);

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < waterMarkContent.length(); i++) {
                char tempChar = waterMarkContent.charAt(i);
                tempCharLen = getCharLen(tempChar, g);//获取标题长度
                tempLineLen += tempCharLen;
                if (tempLineLen >= waterWidth) {
                    huanHangCount++;
                    g.drawString(sb.toString(), tempX, tempY);// 长度已经满一行,进行文字叠加
                    sb.delete(0, sb.length());// 清空内容,重新追加
                    tempY = tempY + fontSize;// 长度已经满一行,Y的位置加10字符高度
                    tempLineLen = 0;
                }
                sb.append(tempChar);// 追加字符
            }
            // 通过设置后两个输入参数给水印定位
            g.drawString(sb.toString(), tempX, tempY);// 最后叠加余下的文字
        }
        g.setColor(Color.BLACK);
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.2f));// 1.0f为透明度 ，值从0-1.0，依次变得不透明
        g.fillRect(tempX-10, firstY - (fontSize + 10), waterWidth + fontSize, (bgWidthLen + 2) * fontSize);

        g.dispose();

        // 输出图片
        try (FileOutputStream outImgStream = new FileOutputStream(srcImgPath);) {
            ImageIO.write(bufImg, FileUtil.getSuffix(srcImgPath), outImgStream);
            outImgStream.flush();
        } catch (IOException e) {
            throw new ServiceException("写入图片文件失败");
        }
    }

    public static int getCharLen(char c, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charWidth(c);
    }

    /**
     * 获取水印文字总长度
     *
     * @param waterMarkContent 水印的文字
     * @param g
     * @return 水印文字总长度
     */
    public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charsWidth(
                waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }

    public static void aaa() {
        String rxPath = "/Users/liutao/Downloads/1.png";
        String lon = StrUtil.format("经  度：{}", 112.90943534);
        String lat = StrUtil.format("纬  度：{}", 89.232132121);

        String address = StrUtil.format("地  址：{}", "湖南省长沙市开福区四方坪街道长城万富汇银座湖南省长沙市开福区四方坪街道长城万富汇银座");

        String pointName = StrUtil.format("点位名称：{}", "测试点位");
        String nowDate = StrUtil.format("时  间：{}", DateUtil.now());
        List<String> contentList = Lists.newArrayList();
        contentList.add(lon);
        contentList.add(lat);
        contentList.add(address);
        contentList.add(pointName);
        contentList.add(nowDate);
        waterPress(rxPath, Color.WHITE, 30, contentList);
    }

    public static void main(String[] args) throws IOException {
//        String source = "/Users/liutao/Downloads/1.jpg";
//        String newPath = "/Users/liutao/Downloads";
//        System.out.println(moreTextWaterMark(source, newPath, "111", "jpg"));

        aaa();

//        String lon = StrUtil.format("经  度：{}", 112.90943534);
//        String lat = StrUtil.format("纬  度：{}", 89.232132121);
//
//        String address = StrUtil.format("地  址：{}", "湖南省长沙市开福区四方坪街道长城万富汇银座湖南省长沙市开福区四方坪街道长城万富汇银座");
//
//        String pointName = StrUtil.format("点位名称：{}", "测试点位");
//        String nowDate = StrUtil.format("时  间：{}", DateUtil.now());
//        List<String> contentList = Lists.newArrayList();
//        contentList.add(lon);
//        contentList.add(lat);
//        contentList.add(address);
//        contentList.add(pointName);
//        contentList.add(nowDate);
//
//        try(FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault("/Users/liutao/Downloads/332_1697546624.mp4");
//            FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("/Users/liutao/Downloads/1.mp4",
//                    grabber.getImageWidth(), grabber.getImageHeight(), 2);
//            Java2DFrameConverter converter = new Java2DFrameConverter();) {
//            grabber.start();
//
//
//            // 视频相关配置，取原视频配置
//            recorder.setFrameRate(grabber.getFrameRate());
//            recorder.setVideoCodec(grabber.getVideoCodec());
//            recorder.setVideoBitrate(grabber.getVideoBitrate());
////        avutil.av_log_set_level(AV_LOG_ERROR);   //设置打印日志级别
//            // 音频相关配置，取原音频配置
//            recorder.setSampleRate(grabber.getSampleRate());
//            recorder.setAudioCodec(avcodec.AV_CODEC_ID_MP3);
//
//            recorder.start();
//            System.out.println("准备开始推流...");
//
//            Frame frame;
//            int i = 0;
//            while ((frame = grabber.grab()) != null) {
//                // 从视频帧中获取图片
//                if (frame.image != null) {
//
//                    BufferedImage bufferedImage = converter.getBufferedImage(frame);
//
//                    // 对图片进行文本合入
////                    for (String s : contentList) {
//                        bufferedImage = addSubtitle(bufferedImage, contentList);
////                    }
//
//                    // 视频帧赋值，写入输出流
//                    recorder.record(converter.getFrame(bufferedImage));
//                }
//
//                // 音频帧写入输出流
//                if(frame.samples != null) {
//                    recorder.record(frame);
//                }
//            }
//            System.out.println("推流结束...");
//            grabber.stop();
//            recorder.stop();
//        } catch (FrameGrabber.Exception | FrameRecorder.Exception e) {
//            e.printStackTrace();
//        }


    }
}